package rexsee.activity;

import java.io.File;
import java.lang.reflect.Field;
import java.security.Provider;
import java.security.Provider.Service;
import java.security.Security;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import rexsee.baidu.RexseeBaiduPCS;
import rexsee.baidu.RexseeBaiduStatistic;
import rexsee.barcode.RexseeBarcode;
import rexsee.cartoon.RexseeCartoon;
import rexsee.cartoon.gif.RexseeGifDialog;
import rexsee.communication.RexseeEmail;
import rexsee.communication.RexseeMMS;
import rexsee.communication.RexseeSMS;
import rexsee.communication.RexseeSMSSender;
import rexsee.communication.RexseeSendTo;
import rexsee.content.RexseeAccounts;
import rexsee.content.RexseeCallLog;
import rexsee.content.RexseeContacts;
import rexsee.content.RexseeContent;
import rexsee.core.alarm.RexseeAlarm;
import rexsee.core.alarm.RexseeKeyguard;
import rexsee.core.alarm.RexseeWakeLock;
import rexsee.core.animation.RexseeTransition;
import rexsee.core.application.Resource;
import rexsee.core.application.RexseeApplication;
import rexsee.core.application.RexseeApplicationManager;
import rexsee.core.application.RexseeConfiguration;
import rexsee.core.application.RexseeIntent;
import rexsee.core.application.RexseeInterfaceManager;
import rexsee.core.browser.Browser;
import rexsee.core.browser.RexseeBrowserStyle;
import rexsee.core.browser.RexseeClient;
import rexsee.core.browser.RexseeCookie;
import rexsee.core.browser.RexseeInception;
import rexsee.core.browser.RexseePregFilter;
import rexsee.core.browser.RexseeUrl;
import rexsee.core.browser.clazz.ExtensionListener;
import rexsee.core.browser.clazz.FilterListener;
import rexsee.core.browser.clazz.History;
import rexsee.core.browser.clazz.HistoryItem;
import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.browser.clazz.RootViewInterface;
import rexsee.core.browser.clazz.UrlListener;
import rexsee.core.lang.RexseeLanguage;
import rexsee.core.lang.RexseeLanguageInterface;
import rexsee.core.layout.Layout;
import rexsee.core.layout.RexseeButtonBars;
import rexsee.core.layout.RexseeLayoutStyle;
import rexsee.core.layout.RexseeStatusBar;
import rexsee.core.layout.RexseeTabBars;
import rexsee.core.layout.RexseeTabs;
import rexsee.core.layout.RexseeTitleBar;
import rexsee.core.menu.PopMenu;
import rexsee.core.menu.PopMenuItem;
import rexsee.core.menu.RexseeMenu;
import rexsee.core.notification.RexseeNotification;
import rexsee.core.progress.RexseeProgressBarDialog;
import rexsee.core.progress.RexseeProgressTextDialog;
import rexsee.core.storage.RexseeAsset;
import rexsee.core.storage.RexseeCursor;
import rexsee.core.storage.RexseeDatabase;
import rexsee.core.storage.RexseeFile;
import rexsee.core.storage.RexseePreference;
import rexsee.core.storage.RexseeStorage;
import rexsee.core.storage.RexseeZIP;
import rexsee.core.style.RexseeDrawable;
import rexsee.core.style.StyleSheet;
import rexsee.core.transportation.RexseeAdvanceDownload;
import rexsee.core.transportation.RexseeAjax;
import rexsee.core.transportation.RexseeDownload;
import rexsee.core.transportation.RexseeProfessionalUpload;
import rexsee.core.transportation.RexseeUpload;
import rexsee.core.utilities.RexseeArray;
import rexsee.core.utilities.RexseeClazz;
import rexsee.core.utilities.RexseeHashMap;
import rexsee.core.utilities.RexseeString;
import rexsee.core.utilities.RexseeUtilities;
import rexsee.core.utilities.Utilities;
import rexsee.device.RexseeBattery;
import rexsee.device.RexseeBuild;
import rexsee.device.RexseeInputMethod;
import rexsee.device.RexseeLocale;
import rexsee.device.RexseeRingtone;
import rexsee.device.RexseeScreen;
import rexsee.device.RexseeSpecialKey;
import rexsee.device.RexseeTelephony;
import rexsee.device.RexseeVibrate;
import rexsee.device.RexseeWallpaper;
import rexsee.dialog.RexseeButtonDialog;
import rexsee.dialog.RexseeChronometer;
import rexsee.dialog.RexseeDialog;
import rexsee.dialog.RexseeImageDialog;
import rexsee.dialog.RexseePopupWindow;
import rexsee.ebook.RexseePageFlip;
import rexsee.fileSelector.RexseeFileSelector;
import rexsee.fileSelector.RexseeFolderSelector;
import rexsee.fileSelector.RexseeSaveAs;
import rexsee.fingerdrawing.RexseeFingerDrawing;
import rexsee.instrumentation.RexseeInstrumentation;
import rexsee.location.RexseeCellLocation;
import rexsee.location.RexseeGps;
import rexsee.multimedia.RexseeAudio;
import rexsee.multimedia.RexseeAudioCapture;
import rexsee.multimedia.RexseeAudioPlayer;
import rexsee.multimedia.RexseeAudioRecorder;
import rexsee.multimedia.RexseeCamera;
import rexsee.multimedia.RexseeCameraPreview;
import rexsee.multimedia.RexseeImage;
import rexsee.multimedia.RexseeImageCapture;
import rexsee.multimedia.RexseeVideoCapture;
import rexsee.multimedia.RexseeVideoPlayer;
import rexsee.natives.RexseeJavaBar;
import rexsee.natives.RexseeJavaDialog;
import rexsee.natives.RexseeJavaView;
import rexsee.network.RexseeAPN;
import rexsee.network.RexseeBluetooth;
import rexsee.network.RexseeBluetoothPrinter;
import rexsee.network.RexseeInstantAudio;
import rexsee.network.RexseeNetwork;
import rexsee.network.RexseeSocket;
import rexsee.network.RexseeVPN;
import rexsee.network.RexseeWiFi;
import rexsee.script.RexseeScript;
import rexsee.security.RexseeCheckSum;
import rexsee.security.RexseeDigest;
import rexsee.security.RexseeEncryption;
import rexsee.security.RexseeKeyPairGenerator;
import rexsee.security.RexseeSecurity;
import rexsee.security.RexseeSignature;
import rexsee.sensor.RexseeSensorAccelerometer;
import rexsee.sensor.RexseeSensorLight;
import rexsee.sensor.RexseeSensorMagneticField;
import rexsee.sensor.RexseeSensorOrientation;
import rexsee.sensor.RexseeSensorProximity;
import rexsee.sensor.RexseeSensorTemperature;
import rexsee.service.RexseePushHttpListener;
import rexsee.service.RexseePushInterface;
import rexsee.service.RexseePushSmsListener;
import rexsee.service.RexseeReliableSubmit;
import rexsee.service._Service;
import rexsee.xml.RexseeXML;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Environment;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Groups;
import android.provider.ContactsContract.RawContacts;
import android.telephony.TelephonyManager;
import android.webkit.WebBackForwardList;
import android.webkit.WebSettings;

public class RexseeActivityInit {

	public static void initUserAgent(Browser browser) {
		Context context = browser.getContext();
		String sim = "", phone = "", subscriber = "";
		try {
			TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			phone = tm.getDeviceId();
			if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
				sim = tm.getSimSerialNumber();
				subscriber = tm.getSubscriberId();
			} else {
				sim = "null";
				subscriber = "null";
			}
		} catch (Exception e) {
		}
		WebSettings websettings = browser.getSettings();
		String newUserAgent = websettings.getUserAgentString().split(browser.application.resources.prefix + ":")[0] + " "
				+ browser.application.resources.prefix + ":" + browser.application.getEditionName() + "/"
				+ browser.application.language + "-" + browser.application.country + "/"
				+ browser.application.screenWidth + "x" + browser.application.screenHeight + "x" + browser.application.screenDensity + "/"
				+ sim + "/" + subscriber + "/" + phone + "/"
				+ context.getPackageName();
		websettings.setUserAgentString(newUserAgent);
		RexseeApplication.setUserAgent(context, newUserAgent);
	}

	public static void initLayoutJavaScriptInterface(Layout layout) {
		Context context = layout.getContext();
		Resources r = context.getResources();
		String packageName = context.getPackageName();
		if (Resource.isEnabled(r, packageName, RexseeTitleBar.INTERFACE_NAME, true)) layout.browser.interfaceList.add(new RexseeTitleBar(layout));
		if (Resource.isEnabled(r, packageName, RexseeStatusBar.INTERFACE_NAME, true)) layout.browser.interfaceList.add(new RexseeStatusBar(layout));
	}
	public static void initPredefinedJavaScriptInterface(Browser browser) {
		Context context = browser.getContext();
		Resources r = context.getResources();
		String packageName = context.getPackageName();
		browser.interfaceList.add(browser.function);
		browser.interfaceList.add(browser.garbageCollector);
		browser.interfaceList.add(browser.touchEvent);
		browser.interfaceList.add(browser.urlListeners);
		browser.interfaceList.add(browser.application);
		browser.interfaceList.add(browser.menu);
		browser.interfaceList.add(browser.progressDialog);
		browser.interfaceList.add(browser.progressCover);
		browser.interfaceList.add(browser.promptListeners);
		browser.interfaceList.add(browser.preload);
		if (Resource.isEnabled(r, packageName, RexseeUtilities.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeUtilities(browser));
		if (Resource.isEnabled(r, packageName, RexseeString.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeString(browser));
		if (Resource.isEnabled(r, packageName, RexseeArray.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeArray(browser));
		if (Resource.isEnabled(r, packageName, RexseeHashMap.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeHashMap(browser));
		if (Resource.isEnabled(r, packageName, RexseeDialog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeDialog(browser));
		if (Resource.isEnabled(r, packageName, RexseeAjax.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAjax(browser));
		if (Resource.isEnabled(r, packageName, RexseePopupWindow.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseePopupWindow(browser));
		if (Resource.isEnabled(r, packageName, RexseeDownload.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeDownload(browser));
		if (Resource.isEnabled(r, packageName, RexseeUpload.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeUpload(browser));
		if (Resource.isEnabled(r, packageName, RexseeVibrate.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeVibrate(browser));
		if (Resource.isEnabled(r, packageName, RexseeCartoon.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCartoon(browser));
		if (Resource.isEnabled(r, packageName, RexseeGifDialog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeGifDialog(browser));
	}
	public static void initDefaultJavaScriptInterface(RootViewInterface rootView) {

		Browser browser = rootView.getBrowser();
		Context context = browser.getContext();
		Resources r = context.getResources();
		String packageName = context.getPackageName();

		if (Resource.isEnabled(r, packageName, RexseeLayoutStyle.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeLayoutStyle(rootView));
		if (Resource.isEnabled(r, packageName, RexseeButtonBars.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeButtonBars(rootView));
		if (Resource.isEnabled(r, packageName, RexseeTabBars.INTERFACE_NAME, true)) {
			RexseeTabBars tabBars = new RexseeTabBars(rootView);
			browser.interfaceList.add(tabBars);
			if (Resource.isEnabled(r, packageName, RexseeTabs.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeTabs(browser, tabBars));
		}

		if (Resource.isEnabled(r, packageName, RexseeStorage.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeStorage(browser));
		if (Resource.isEnabled(r, packageName, RexseeDrawable.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeDrawable(browser));
		if (Resource.isEnabled(r, packageName, RexseeConfiguration.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeConfiguration(browser));
		if (Resource.isEnabled(r, packageName, RexseeClazz.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeClazz(browser));
		if (Resource.isEnabled(r, packageName, RexseeTransition.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeTransition(browser));
		if (Resource.isEnabled(r, packageName, RexseeBrowserStyle.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBrowserStyle(browser));
		if (Resource.isEnabled(r, packageName, RexseeButtonDialog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeButtonDialog(browser));
		if (Resource.isEnabled(r, packageName, RexseeImageDialog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeImageDialog(browser));
		if (Resource.isEnabled(r, packageName, RexseeProgressBarDialog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeProgressBarDialog(browser));
		if (Resource.isEnabled(r, packageName, RexseeProgressTextDialog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeProgressTextDialog(browser));
		if (Resource.isEnabled(r, packageName, RexseeChronometer.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeChronometer(browser));
		if (Resource.isEnabled(r, packageName, RexseeInception.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeInception(browser));
		if (Resource.isEnabled(r, packageName, RexseePregFilter.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseePregFilter(browser));
		if (Resource.isEnabled(r, packageName, RexseeSpecialKey.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSpecialKey(browser));
		if (Resource.isEnabled(r, packageName, RexseeInputMethod.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeInputMethod(browser));
		if (Resource.isEnabled(r, packageName, RexseeIntent.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeIntent(browser));
		if (Resource.isEnabled(r, packageName, RexseeXML.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeXML(browser));
		if (Resource.isEnabled(r, packageName, RexseePageFlip.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseePageFlip(browser));

		if (Resource.isEnabled(r, packageName, RexseeImage.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeImage(browser));
		if (Resource.isEnabled(r, packageName, RexseeAudioRecorder.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAudioRecorder(browser));
		if (Resource.isEnabled(r, packageName, RexseeCamera.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCamera(browser));
		if (Resource.isEnabled(r, packageName, RexseeAudioPlayer.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAudioPlayer(browser));
		if (Resource.isEnabled(r, packageName, RexseeVideoPlayer.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeVideoPlayer(browser));

		if (Resource.isEnabled(r, packageName, RexseeSensorAccelerometer.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSensorAccelerometer(browser));
		if (Resource.isEnabled(r, packageName, RexseeSensorOrientation.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSensorOrientation(browser));
		if (Resource.isEnabled(r, packageName, RexseeSensorLight.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSensorLight(browser));
		if (Resource.isEnabled(r, packageName, RexseeSensorProximity.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSensorProximity(browser));
		if (Resource.isEnabled(r, packageName, RexseeSensorTemperature.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSensorTemperature(browser));
		if (Resource.isEnabled(r, packageName, RexseeSensorMagneticField.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSensorMagneticField(browser));

		if (Resource.isEnabled(r, packageName, RexseeBarcode.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBarcode(browser));

		if (Resource.isEnabled(r, packageName, RexseeJavaView.INTERFACE_NAME, true)) {
			RexseeJavaView views = new RexseeJavaView(browser);
			browser.interfaceList.add(views);
			if (Resource.isEnabled(r, packageName, RexseeJavaDialog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeJavaDialog(browser, views));
			if (Resource.isEnabled(r, packageName, RexseeJavaBar.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeJavaBar(rootView, views));
		}

		if (Resource.isEnabled(r, packageName, RexseeScript.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeScript(browser));

		if (Resource.isEnabled(r, packageName, RexseeBaiduPCS.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBaiduPCS(browser));
		if (Resource.isEnabled(r, packageName, RexseeBaiduStatistic.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBaiduStatistic(browser));

	}
	public static void initRiskyJavaScriptInterface(RootViewInterface rootView) {

		Browser browser = rootView.getBrowser();
		Context context = browser.getContext();
		Resources r = context.getResources();
		String packageName = context.getPackageName();

		if (Resource.isEnabled(r, packageName, RexseeScreen.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeScreen(rootView));

		if (Resource.isEnabled(r, packageName, RexseeClient.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeClient(browser));
		if (Resource.isEnabled(r, packageName, RexseeApplicationManager.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeApplicationManager(browser));
		if (Resource.isEnabled(r, packageName, RexseeLanguageInterface.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeLanguageInterface(browser));
		if (Resource.isEnabled(r, packageName, RexseeInstrumentation.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeInstrumentation(browser));
		if (Resource.isEnabled(r, packageName, RexseeCookie.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCookie(browser));
		if (Resource.isEnabled(r, packageName, RexseeInterfaceManager.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeInterfaceManager(browser));
		if (Resource.isEnabled(r, packageName, RexseeNotification.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeNotification(browser));
		if (Resource.isEnabled(r, packageName, RexseeAdvanceDownload.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAdvanceDownload(browser));
		if (Resource.isEnabled(r, packageName, RexseeBattery.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBattery(browser));
		if (Resource.isEnabled(r, packageName, RexseeTelephony.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeTelephony(browser));
		if (Resource.isEnabled(r, packageName, RexseeWallpaper.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeWallpaper(browser));
		if (Resource.isEnabled(r, packageName, RexseeBuild.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBuild(browser));
		if (Resource.isEnabled(r, packageName, RexseeLocale.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeLocale(browser));
		if (Resource.isEnabled(r, packageName, RexseeWakeLock.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeWakeLock(browser));
		if (Resource.isEnabled(r, packageName, RexseeKeyguard.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeKeyguard(browser));
		if (Resource.isEnabled(r, packageName, RexseeAlarm.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAlarm(browser));
		if (Resource.isEnabled(r, packageName, RexseeProfessionalUpload.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeProfessionalUpload(browser));
		if (Resource.isEnabled(r, packageName, RexseeRingtone.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeRingtone(browser));
		if (Resource.isEnabled(r, packageName, RexseeSMS.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSMS(browser));
		if (Resource.isEnabled(r, packageName, RexseeSMSSender.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSMSSender(browser));
		if (Resource.isEnabled(r, packageName, RexseeSendTo.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSendTo(browser));
		if (Resource.isEnabled(r, packageName, RexseeMMS.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeMMS(browser));
		if (Resource.isEnabled(r, packageName, RexseeEmail.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeEmail(browser));
		if (Resource.isEnabled(r, packageName, RexseeCameraPreview.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCameraPreview(browser));
		if (Resource.isEnabled(r, packageName, RexseeImageCapture.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeImageCapture(browser));
		if (Resource.isEnabled(r, packageName, RexseeVideoCapture.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeVideoCapture(browser));
		if (Resource.isEnabled(r, packageName, RexseeAudioCapture.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAudioCapture(browser));
		if (Resource.isEnabled(r, packageName, RexseeAudio.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAudio(browser));

		if (Resource.isEnabled(r, packageName, RexseeNetwork.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeNetwork(browser));
		if (Resource.isEnabled(r, packageName, RexseeWiFi.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeWiFi(browser));
		if (Resource.isEnabled(r, packageName, RexseeSocket.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSocket(browser));
		if (Resource.isEnabled(r, packageName, RexseeAPN.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAPN(browser));
		if (Resource.isEnabled(r, packageName, RexseeVPN.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeVPN(browser));
		if (Resource.isEnabled(r, packageName, RexseeInstantAudio.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeInstantAudio(browser));
		if (Resource.isEnabled(r, packageName, RexseeBluetooth.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBluetooth(browser));
		if (Resource.isEnabled(r, packageName, RexseeBluetoothPrinter.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeBluetoothPrinter(browser));

		if (Resource.isEnabled(r, packageName, RexseePreference.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseePreference(browser));
		if (Resource.isEnabled(r, packageName, RexseeDatabase.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeDatabase(browser));
		if (Resource.isEnabled(r, packageName, RexseeCursor.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCursor(browser));
		if (Resource.isEnabled(r, packageName, RexseeFile.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeFile(browser));
		if (Resource.isEnabled(r, packageName, RexseeAsset.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAsset(browser));
		if (Resource.isEnabled(r, packageName, RexseeFileSelector.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeFileSelector(browser));
		if (Resource.isEnabled(r, packageName, RexseeFolderSelector.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeFolderSelector(browser));
		if (Resource.isEnabled(r, packageName, RexseeSaveAs.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSaveAs(browser));

		//rexsee.security
		if (Resource.isEnabled(r, packageName, RexseeSecurity.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSecurity(browser));
		if (Resource.isEnabled(r, packageName, RexseeKeyPairGenerator.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeKeyPairGenerator(browser));
		if (Resource.isEnabled(r, packageName, RexseeDigest.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeDigest(browser));
		if (Resource.isEnabled(r, packageName, RexseeEncryption.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeEncryption(browser));
		if (Resource.isEnabled(r, packageName, RexseeSignature.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeSignature(browser));
		if (Resource.isEnabled(r, packageName, RexseeCheckSum.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCheckSum(browser));
		if (Resource.isEnabled(r, packageName, RexseeZIP.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeZIP(browser));

		//rexsee.location
		if (Resource.isEnabled(r, packageName, RexseeGps.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeGps(browser));
		if (Resource.isEnabled(r, packageName, RexseeCellLocation.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCellLocation(browser));

		//rexsee.content
		if (Resource.isEnabled(r, packageName, RexseeContent.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeContent(browser));
		if (Resource.isEnabled(r, packageName, RexseeCallLog.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeCallLog(browser));
		if (Resource.isEnabled(r, packageName, RexseeContacts.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeContacts(browser));
		if (Resource.isEnabled(r, packageName, RexseeAccounts.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeAccounts(browser));

		//rexsee.fingerdrawing
		if (Resource.isEnabled(r, packageName, RexseeFingerDrawing.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeFingerDrawing(browser));

	}
	public static void initServiceJavaScriptInterface(RootViewInterface rootView) {

		Browser browser = rootView.getBrowser();
		Context context = browser.getContext();
		Resources r = context.getResources();
		String packageName = context.getPackageName();

		/*By adding following declaration in AndroidManifest.xml:
		 *<receiver android:name="rexsee.standard._Receiver">
		 *	<intent-filter>
		 *		<action android:name="android.intent.action.BOOT_COMPLETED" />
		 *	</intent-filter>
		 *</receiver>
		 *<service android:name="rexsee.service._Service"/>
		 */
		if (Resource.isEnabled(r, packageName, RexseePushInterface.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseePushInterface(browser));
		if (Resource.isEnabled(r, packageName, RexseePushSmsListener.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseePushSmsListener(browser));
		if (Resource.isEnabled(r, packageName, RexseePushHttpListener.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseePushHttpListener(browser));
		if (Resource.isEnabled(r, packageName, RexseeReliableSubmit.INTERFACE_NAME, true)) browser.interfaceList.add(new RexseeReliableSubmit(browser));
		try {
			if (context.startService(new Intent(context, _Service.class)) == null) browser.exception("Activity", "Start service failed.");
		} catch (Exception e) {

		}

	}

	public static void initBasicUrlListener(Browser browser) {

		browser.urlListeners.addExtension(new ExtensionListener(new String[]{"htm", "html"}) {
			@Override
			public boolean shouldProcessOnline() {
				return false;
			}
			@Override
			public boolean shouldProcessLocal() {
				return true;
			}
			@Override
			public boolean shouldAddToHistory(String url) {
				return true;
			}
			@Override
			public void run(Context context, final Browser browser, final String url) {
				browser.pageBeforeStartListeners.run(browser, url);
				browser.loadUrl(url);
			}
		});
		browser.urlListeners.addExtension(new ExtensionListener(new String[]{"xml", "xhtml", "smil"}) {
			@Override
			public boolean shouldProcessOnline() {
				return true;
			}
			@Override
			public boolean shouldProcessLocal() {
				return true;
			}
			@Override
			public boolean shouldAddToHistory(String url) {
				return true;
			}
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				browser.pageBeforeStartListeners.run(browser, url);
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String code = browser.urlListeners.getContent(url);
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						if (code.startsWith(RexseeApplication.EXCEPTION_PREFIX)) {
							browser.progressDialog.hide();
							browser.exception("InitBasicUrlListener", code);
						} else {
							browser.progressDialog.hide();
							String formatedCode = browser.urlListeners.formatXmlFile_(url, code);
							browser.function.loadHTMLWithoutHistory(formatedCode);
						}
					}
				}.start();
			}
		});
		browser.urlListeners.addExtension(new ExtensionListener(new String[]{"java", "txt", "js", "css", "log", "cfg"}) {
			@Override
			public boolean shouldProcessOnline() {
				return false;
			}
			@Override
			public boolean shouldProcessLocal() {
				return true;
			}
			@Override
			public boolean shouldAddToHistory(String url) {
				return true;
			}
			@Override
			public void run(Context context, final Browser browser, final String url) {
				browser.pageBeforeStartListeners.run(browser, url);
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String code = browser.urlListeners.getContent(url);
						String formatedCode = browser.urlListeners.formatTextFile_(url, code);
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(formatedCode);
					}
				}.start();
			}
		});
		browser.urlListeners.addExtension(new ExtensionListener(new String[]{"jpg", "jpeg", "png", "gif"}) {
			@Override
			public boolean shouldProcessOnline() {
				return true;
			}
			@Override
			public boolean shouldProcessLocal() {
				return true;
			}
			@Override
			public boolean shouldAddToHistory(String url) {
				return true;
			}
			@Override
			public void run(Context context, final Browser browser, final String url) {
				browser.pageBeforeStartListeners.run(browser, url);
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String code = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD><BODY style='margin:0px;'>";
						code += "<IMG src='" + url + "' width=100%/>";
						code += "</BODY></HTML>";
						browser.progressDialog.hide();
						if (url.toLowerCase().startsWith("http://") || url.toLowerCase().startsWith("https://")) {
							browser.history.add(url);
						}
						browser.function.loadHTMLWithoutHistory(code);
					}
				}.start();
			}
		});
		browser.urlListeners.addExtension(new ExtensionListener(new String[]{"db"}) {
			@Override
			public boolean shouldProcessOnline() {
				return false;
			}
			@Override
			public boolean shouldProcessLocal() {
				return true;
			}
			@Override
			public boolean shouldAddToHistory(String url) {
				return false;
			}
			@Override
			public void run(Context context, Browser browser, String url) {
				Uri uri = Uri.parse(url);
				String scheme = uri.getScheme();
				if (scheme == null || !scheme.equals("file")) {
					browser.application.error("Can't process .db file online.");
					return;
				}
				File file = new File(uri.getPath());
				if (!file.exists()) {
					browser.application.error("File " + file.getAbsolutePath() + " not found.");
					return;
				}
				if (file.isDirectory()) {
					browser.application.error("The .db file is a directory.");
					return;
				}
				browser.function.go("database://" + file.getAbsolutePath());
			}
		});

		browser.urlListeners.add(new UrlListener("http://") {
			@Override
			public void run(Context context, Browser browser, String url) {
				if (browser.domainWhiteList.isValidUrl(url)) {
					FilterListener filterListener = browser.urlListeners.getFilterByUrl(url);
					if (filterListener != null) {
						filterListener.run(context, browser, url);
						return;
					}
					ExtensionListener extensionListener = browser.urlListeners.getExtensionByUrl(url);
					if (extensionListener != null && extensionListener.shouldProcessOnline()) {
						extensionListener.run(context, browser, url);
						return;
					}
					browser.pageBeforeStartListeners.run(browser, url);
					browser.loadUrl(url);
				} else {
					Intent i = new Intent();
					i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
					i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					i.setAction(Intent.ACTION_VIEW);
					i.setData(Uri.parse(url));
					context.startActivity(i);
				}
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				if (browser.domainWhiteList.isValidUrl(url)) {
					ExtensionListener extensionListener = browser.urlListeners.getExtensionByUrl(url);
					if (extensionListener != null && extensionListener.shouldProcessOnline()) {
						return extensionListener.shouldAddToHistory(url);
					} else {
						return true;
					}
				} else {
					return false;
				}
			}
		});
		browser.urlListeners.add(new UrlListener("https://") {
			@Override
			public void run(Context context, Browser browser, String url) {
				if (browser.domainWhiteList.isValidUrl(url)) {
					FilterListener filterListener = browser.urlListeners.getFilterByUrl(url);
					if (filterListener != null) {
						filterListener.run(context, browser, url);
						return;
					}
					ExtensionListener extensionListener = browser.urlListeners.getExtensionByUrl(url);
					if (extensionListener != null && extensionListener.shouldProcessOnline()) {
						extensionListener.run(context, browser, url);
						return;
					}
					browser.pageBeforeStartListeners.run(browser, url);
					browser.loadUrl(url);
				} else {
					Intent i = new Intent();
					i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
					i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					i.setAction(Intent.ACTION_VIEW);
					i.setData(Uri.parse(url));
					context.startActivity(i);
				}
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				if (browser.domainWhiteList.isValidUrl(url)) {
					ExtensionListener extensionListener = browser.urlListeners.getExtensionByUrl(url);
					if (extensionListener != null && extensionListener.shouldProcessOnline()) {
						return extensionListener.shouldAddToHistory(url);
					} else {
						return true;
					}
				} else {
					return false;
				}
			}
		});
		browser.urlListeners.add(new UrlListener("tel:") {
			@Override
			public void run(Context context, Browser browser, String url) {
				Intent i = new Intent();
				i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
				i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				i.setAction(Intent.ACTION_DIAL);
				i.setData(Uri.parse(url));
				context.startActivity(i);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener("wtai://") {
			@Override
			public void run(Context context, Browser browser, String url) {
				Intent i = new Intent();
				i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
				i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				i.setAction(Intent.ACTION_DIAL);
				String newUrl = "tel:" + url.substring(url.indexOf(";") + 1).trim().replace(" ", "").replace("-", "").replace("_", "");
				i.setData(Uri.parse(newUrl));
				context.startActivity(i);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener("smsto:") {
			@Override
			public void run(Context context, Browser browser, String url) {
				Intent i = new Intent();
				i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
				i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				i.setAction(Intent.ACTION_SENDTO);
				i.setData(Uri.parse(url));
				context.startActivity(i);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener("sms:") {
			@Override
			public void run(Context context, Browser browser, String url) {
				Intent i = new Intent();
				i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
				i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				i.setAction(Intent.ACTION_SENDTO);
				i.setData(Uri.parse("smsto" + url.substring(url.indexOf(":"))));
				context.startActivity(i);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener("mailto:") {
			@Override
			public void run(Context context, Browser browser, String url) {
				Intent i = new Intent();
				i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
				i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				i.setAction(Intent.ACTION_SENDTO);
				i.setData(Uri.parse(url));
				context.startActivity(i);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener("javascript:") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.loadUrl(url);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener("js:") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.loadUrl("javascript" + url.substring(url.indexOf(":")));
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});

		final String prefix = browser.application.resources.prefix;

		browser.urlListeners.add(new UrlListener(prefix + ":error") {
			@Override
			public void run(Context context, Browser browser, String url) {
				String defaultError = "<html><head><title>" + RexseeLanguage.TITLE_ERROR + "</title></head><body style='background-color:#000000;color:#FFFFFF;'>" + RexseeLanguage.MESSAGE_WEAK_NETWORK + "</body></html>";
				String html;
				try {
					byte[] bytes = Utilities.getAssetContent(context, "error.html");
					html = (bytes == null) ? defaultError : new String(bytes, "UTF-8");
				} catch (Exception e) {
					html = defaultError;
				}
				browser.function.loadHTMLWithoutHistory(html);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":html") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.function.showWithoutHistory(RexseeLanguage.TITLE_ERROR, RexseeLanguage.MESSAGE_PAGE_EXPIRED);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":info") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.pageBeforeStartListeners.run(browser, url);
				ArrayList<UrlListener> urlList = browser.urlListeners.listeners;
				String urlString = "";
				for (int i = 0; i < urlList.size(); i++) {
					urlString += "<DIV>" + urlList.get(i).url + "</DIV>";
				}
				ArrayList<JavascriptInterface> interfaceList = browser.interfaceList.getList();
				String interfaceString = "";
				for (int i = 0; i < interfaceList.size(); i++) {
					JavascriptInterface face = interfaceList.get(i);
					if (browser.parentBrowser == null) {
						interfaceString += "<DIV>" + face.getInterfaceName() + ": new</DIV>";
					} else {
						JavascriptInterface parent = browser.parentBrowser.interfaceList.get(face.getInterfaceName());
						if (parent == null) {
							interfaceString += "<DIV style='color:red;'>" + face.getInterfaceName() + ": only here</DIV>";
						} else if (parent.equals(face)) {
							interfaceString += "<DIV style='color:blue;'>" + face.getInterfaceName() + ": inherite from parent</DIV>";
						} else {
							interfaceString += "<DIV>" + face.getInterfaceName() + ": new</DIV>";
						}
						parent = null;
					}
				}
				ArrayList<String> whiteList = browser.domainWhiteList.getList();
				String whiteString = "";
				for (int i = 0; i < whiteList.size(); i++) {
					whiteString += "<DIV>" + whiteList.get(i) + "</DIV>";
				}
				String styleString = "";
				Field[] styleFields = StyleSheet.class.getFields();
				for (int i = 0; i < styleFields.length; i++) {
					styleString += "<DIV>" + styleFields[i].getName().replace("_", "-") + "</DIV>";
				}
				ArrayList<String> eventList = browser.eventList.list;
				String eventString = "";
				for (int i = 0; i < eventList.size(); i++) {
					eventString += "<DIV>" + eventList.get(i) + "</DIV>";
				}
				String[] promptList = browser.promptListeners.list();
				String promptString = "";
				for (int i = 0; i < promptList.length; i++) {
					promptString += "<DIV>" + promptList[i] + "</DIV>";
				}

				String html = "<HTML><HEAD><TITLE>Rexsee Browser Infomation</TITLE></HEAD><BODY style='line-height:150%;'>" +
						"<DIV style='font-size:14px;padding-top:15px;'><B>User Agent String:</B><DIV style='border:1px solid #7f9db5;padding:10px;'><I>" + browser.getSettings().getUserAgentString() + "</I></DIV></DIV>" +
						"<DIV style='font-size:14px;padding-top:15px;'><B>Url Listeners:</B><DIV style='border:1px solid #7f9db5;padding:10px;'><I>" + urlString + "</I></DIV></DIV>" +
						"<DIV style='font-size:14px;padding-top:15px;'><B>Javascript Interfaces:</B><DIV style='border:1px solid #7f9db5;padding:10px;'><I>" + interfaceString + "</I></DIV></DIV>" +
						"<DIV style='font-size:14px;padding-top:15px;'><B>Domain White List:</B><DIV style='border:1px solid #7f9db5;padding:10px;'><I>" + whiteString + "</I></DIV></DIV>" +
						"<DIV style='font-size:14px;padding-top:15px;'><B>Rexsee Events:</B><DIV style='border:1px solid #7f9db5;padding:10px;'><I>" + eventString + "</I></DIV></DIV>" +
						"<DIV style='font-size:14px;padding-top:15px;'><B>Prompt Types:</B><DIV style='border:1px solid #7f9db5;padding:10px;'><I>" + promptString + "</I></DIV></DIV>" +
						"<DIV style='font-size:14px;padding-top:15px;'><B>Layout Style-Sheet:</B><DIV style='border:1px solid #7f9db5;padding:10px;'><I>" + styleString + "</I></DIV></DIV>" +
						"</BODY></HTML>";
				browser.function.loadHTMLWithoutHistory(html);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":page") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.application.alert("<br>" + browser.history.getCurrentItem().getTitle() + "<br><br>" + "URL: " + browser.history.getCurrentItem().getUrl() + "<br>");
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":about") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.application.alert(RexseeLanguage.TITLE_ABOUT, "<br>" + RexseeLanguage.PREFIX_AUTHOR + " " + browser.application.getAuthorName() + "<br>" + RexseeLanguage.PREFIX_EMAIL + " " + browser.application.getAuthorEmail() + "<br><br>Powered By " + prefix.substring(0, 1).toUpperCase() + prefix.substring(1) + "<br>");
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":quit") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.application.confirmQuit();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":restart") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.application.confirmRestart();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":reload") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.function.reload();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":back") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.function.goBack();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":forward") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.function.goForward();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":stop") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.function.stop();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":history") {
			@Override
			public void run(Context context, final Browser browser, String url) {
				History history = browser.history;
				int currentIndex = history.getCurrentIndex();
				PopMenu popMenu = new PopMenu(browser, prefix + ":history", "label:" + RexseeLanguage.TITLE_HISTORY + ";");
				for (int i = (history.getSize() - 1); i >= 0; i--) {
					String title;
					Runnable runnable;
					HistoryItem historyItem = history.getItemAtIndex(i);
					long time = (historyItem.finishTime > 0) ? historyItem.finishTime - historyItem.startTime : -1;
					if (i == currentIndex) {
						title = "<font color=red>" + historyItem.getTitle() + "<br><I>" + historyItem.getUrl() + "[" + historyItem.getScrollX() + "/" + historyItem.getScrollY() + "][" + time + "]</I></font>";
						runnable = null;
					} else {
						title = historyItem.getTitle() + "<br><I>" + historyItem.getUrl() + "[" + historyItem.getScrollX() + "/" + historyItem.getScrollY() + "][" + time + "]</I>";
						final int steps = i - currentIndex;
						runnable = new Runnable() {
							@Override
							public void run() {
								browser.function.goBackOrForward(steps);
							}
						};
					}
					String s = "label:" + title + ";font-size:14px;label-type:html;";
					PopMenuItem item = new PopMenuItem(context, history.getItemAtIndex(i).getTitle(), runnable, s, s, s);
					popMenu.add(item);
				}
				browser.menu.open(popMenu);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":original_history") {
			@Override
			public void run(Context context, Browser browser, String url) {
				WebBackForwardList history = browser.copyBackForwardList();
				int currentIndex = history.getCurrentIndex();
				PopMenu popMenu = new PopMenu(browser, prefix + ":original_history", "label:WebKit " + RexseeLanguage.TITLE_HISTORY + ";");
				for (int i = (history.getSize() - 1); i >= 0; i--) {
					String title;
					if (i == currentIndex) {
						title = "<font color=red>" + history.getItemAtIndex(i).getTitle() + "<br><I>" + history.getItemAtIndex(i).getUrl() + "</I></font>";
					} else {
						title = history.getItemAtIndex(i).getTitle() + "<br><I>" + history.getItemAtIndex(i).getUrl() + "</I>";
					}
					String s = "label:" + title + ";font-size:14px;";
					PopMenuItem item = new PopMenuItem(context, history.getItemAtIndex(i).getTitle(), null, s, s, s);
					popMenu.add(item);
				}
				browser.menu.open(popMenu);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":menu") {
			@Override
			public void run(Context context, final Browser browser, String url) {
				String[] tmp = url.split("\\?id=");
				PopMenu popMenu = browser.menu.menus.get((tmp.length == 1 || tmp[1].equals("")) ? RexseeMenu.ID_COMMON_MENU : tmp[1]);
				if (popMenu != null) browser.menu.open(popMenu);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":home_setup") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.pageBeforeStartListeners.run(browser, url);
				String home = browser.application.getDeveloperHome();
				String host, port, path;
				if (home.equals(prefix + ":home_setup")) {
					home = "http://";
					host = "http://";
					port = "";
					path = "";
				} else {
					Uri uri = Uri.parse(home);
					host = uri.getScheme() + "://" + ((uri.getHost() == null) ? "" : uri.getHost());
					port = (uri.getPort() < 0) ? "" : String.valueOf(uri.getPort());
					String tmp = host + ((port.equals("")) ? "" : ":" + port);
					path = home.substring(tmp.length());
					if (path.startsWith("//")) path = path.substring(2);
					if (path.startsWith("/")) path = path.substring(1);
				}
				String html = "<HTML><HEAD><TITLE>" + browser.application.label + "</TITLE></HEAD><BODY style='background-color:black;'>" +
						"<table width=100% height=100%><tr><td valign=middle style='padding:5px;font-size:16px;line-height:150%;color:white;'>" +
						"<center><div style='margin-bottom:20px;font-size:24px;'>" + browser.application.label + "</div></center>" +
						"<div style='margin-bottom:20px;'>" + RexseeLanguage.MESSAGE_HOME_SETUP + "</div>" +
						"<table style='font-size:16px;color:white;'>" +
						"<tr><td nowrap>" + RexseeLanguage.PREFIX_HOMEPAGE + "</td><td><input id=homeinput name=homeinput type=text style='width:200px;' value='" + home + "'></td><tr>" +
						"<tr><td colspan=2><button style='margin-top:10px;border:1px solid white;background-color:#444444;color:white;padding:5 20 5 20;' onclick=\"var home=document.getElementById('homeinput').value;" + browser.application.getInterfaceName() + ".setDeveloperHome(home);alert('" + RexseeLanguage.MESSAGE_RESTART + "');" + browser.application.getInterfaceName() + ".restart();\">" + RexseeLanguage.ACTION_SUBMIT + "</button></td><tr>" +
						"<tr><td nowrap>URL/IP: </td><td><input id=urlinput name=homeinput type=text style='width:200px;margin-bottom:3px;margin-top:15px;' value='" + host + "'></td><tr>" +
						"<tr><td nowrap>Port: </td><td><input id=portinput name=homeinput type=text style='width:200px;margin-bottom:3px;' value='" + port + "'></td></tr>" +
						"<tr><td nowrap>Path: </td><td><input id=pathinput name=homeinput type=text style='width:200px;' value='" + path + "'></td></tr>" +
						"<tr><td colspan=2><button style='margin-top:10px;border:1px solid white;background-color:#444444;color:white;padding:5 20 5 20;' onclick=\"var port=(document.getElementById('portinput').value=='')?'':':'+document.getElementById('portinput').value; var home=document.getElementById('urlinput').value+port+'/'+document.getElementById('pathinput').value;" + browser.application.getInterfaceName() + ".setDeveloperHome(home);alert('" + RexseeLanguage.MESSAGE_RESTART + "');" + browser.application.getInterfaceName() + ".restart();\">" + RexseeLanguage.ACTION_SUBMIT + "</button></td></tr>" +
						"</table>" +
						"</td></tr></table>" +
						"</BODY></HTML>";
				browser.function.loadHTMLWithoutHistory(html);
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});

	}

	public static void initContentUrlListener(Browser browser) {

		browser.urlListeners.add(new UrlListener("content://") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
						ContentResolver contentResolver = browser.getContext().getContentResolver();
						String last = url;
						while (last.endsWith("/"))
							last = last.substring(0, last.length() - 1);
						last = url.substring(url.lastIndexOf("/") + 1);
						boolean isInteger = false;
						try {
							int tmp = Integer.parseInt(last);
							tmp++;
							isInteger = true;
						} catch (Exception e) {
						}
						if (!isInteger) {
							try {
								Cursor cursor = contentResolver.query(Uri.parse(url), null, null, null, null);
								for (int i = 0; i < cursor.getColumnCount(); i++) {
									html += "<tr><td style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>" + cursor.getColumnName(i) + "</td></tr>";
								}
								cursor.close();
							} catch (Exception e) {
								html += "<tr><td style='padding:10px;'>Exception: " + e.getLocalizedMessage() + "</td></tr>";
							}
						} else {
							try {
								Cursor cursor = contentResolver.query(Uri.parse(url), null, " _id=?", new String[]{last}, null);
								html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
								if (cursor == null || cursor.getCount() == 0) {
									html += "<tr><td style='padding:10px;'>Content is not found.</td></tr>";
								} else {
									cursor.moveToFirst();
									for (int i = 0; i < cursor.getColumnCount(); i++) {
										html += "<tr><td style='border-bottom:1px solid #222222;word-break:break-all;padding:5px;'>" + cursor.getColumnName(i) + "</td><td style='border-bottom:1px solid #222222;word-break:break-all;padding:5px;padding-left:0px;'>" + cursor.getString(i) + "</td></tr>";
									}
								}
								cursor.close();
							} catch (Exception e) {
								html += "<tr><td style='padding:10px;'>Exception: " + e.getLocalizedMessage() + "</td></tr>";
							}
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener("processes://") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						String path = Uri.parse(url).getSchemeSpecificPart();
						if (path == null || path.equals("") || path.substring(path.lastIndexOf("/") + 1).equals("")) {
							html += "<table width=100% cellspacing=0 style='color:white;font-size:14px;'>";
							ActivityManager am = (ActivityManager) browser.getContext().getSystemService(Context.ACTIVITY_SERVICE);
							List<RunningAppProcessInfo> raps = am.getRunningAppProcesses();
							Iterator<RunningAppProcessInfo> iterator = raps.iterator();
							while (iterator.hasNext()) {
								RunningAppProcessInfo processInfo = iterator.next();
								html += "<tr><td onclick=\"window.open('processes://" + processInfo.processName + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;'>";
								html += "<div style='font-size:16px;'><b>" + processInfo.processName + "</b></div>";
								html += "<div><b>pid:</b>" + processInfo.pid + "</div>";
								html += "<div><b>uid:</b>" + processInfo.uid + "</div>";
								html += "<div><b>importance:</b>" + RexseeApplicationManager.getProcessImportance_(processInfo.importance) + "</div>";
								html += "<div><b>iru:</b>" + processInfo.lru + "</div>";
								html += "<div><b>importanceReason:</b>" + RexseeApplicationManager.getProcessImportanceReason_(processInfo.importanceReasonCode) + "</div>";
								html += "<div><b>importanceReasonPid:</b>" + processInfo.importanceReasonPid + "</div>";
								if (processInfo.importanceReasonComponent == null) {
									html += "<div><b>importanceReasonPackageName:</b></div>";
									html += "<div><b>importanceReasonClassName:</b></div>";
									html += "<div><b>importanceReasonShortClassName:</b></div>";
								} else {
									html += "<div><b>importanceReasonPackageName:</b>" + processInfo.importanceReasonComponent.getPackageName() + "</div>";
									html += "<div><b>importanceReasonClassName:</b>" + processInfo.importanceReasonComponent.getClassName() + "</div>";
									html += "<div><b>importanceReasonShortClassName:</b>" + processInfo.importanceReasonComponent.getShortClassName() + "</div>";
								}
								html += "</td></tr>";
							}
							html += "</table>";
						} else {
							String processName = path.substring(path.lastIndexOf("/") + 1);
							ApplicationInfo appInfo = RexseeApplicationManager.getApplicationInfoByProcessName_(browser.getContext(), processName);
							if (appInfo != null) {
								browser.function.go("apps://" + appInfo.packageName);
								return;
							}
							html += "Cooresponding package is not found.";
						}
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				String path = Uri.parse(url).getSchemeSpecificPart();
				if (path == null || path.equals("") || path.substring(path.lastIndexOf("/") + 1).equals("")) {
					return true;
				} else {
					return false;
				}
			}
		});
		browser.urlListeners.add(new UrlListener("apps://") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						PackageManager pm = browser.getContext().getPackageManager();
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						String path = Uri.parse(url).getSchemeSpecificPart();
						if (path == null || path.equals("") || path.substring(path.lastIndexOf("/") + 1).equals("")) {
							html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
							List<ApplicationInfo> ais = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
							Iterator<ApplicationInfo> iterator = ais.iterator();
							while (iterator.hasNext()) {
								ApplicationInfo appInfo = iterator.next();
								html += "<tr><td onclick=\"window.open('apps://" + appInfo.packageName + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;'>";
								html += "<div>" + appInfo.loadLabel(pm) + "</div>";
								html += "<div style='font-size:14px;color:gray;margin-top:5px;word-break:break-all;'>" + appInfo.packageName + " [" + appInfo.uid + "]</div>";
								html += "</td></tr>";
							}
							html += "</table>";
						} else {
							html += "<table width=100% cellspacing=0 style='color:white;font-size:14px;'><tbody valign=top>";
							String packageName = path.substring(path.lastIndexOf("/") + 1);
							PackageInfo packageInfo;
							try {
								packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SHARED_LIBRARY_FILES | PackageManager.GET_GIDS | PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS | PackageManager.GET_PROVIDERS | PackageManager.GET_SERVICES | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
								html += "<tr><td colspan=2 style='font-size:16px; border-bottom:1px solid #222222; padding:10 5 10 5;'><b>" + packageInfo.applicationInfo.loadLabel(pm) + "</b></td></tr>";
								html += "<tr><td nowrap>packageName:</td><td>" + packageInfo.packageName + "</td></tr>";
								html += "<tr><td nowrap>name:</td><td>" + packageInfo.applicationInfo.name + "</td></tr>";
								html += "<tr><td nowrap>processName:</td><td>" + packageInfo.applicationInfo.processName + "</td></tr>";
								html += "<tr><td nowrap>className:</td><td>" + packageInfo.applicationInfo.className + "</td></tr>";
								html += "<tr><td nowrap>description:</td><td>" + packageInfo.applicationInfo.loadDescription(pm) + "</td></tr>";
								html += "<tr><td nowrap>uid:</td><td>" + packageInfo.applicationInfo.uid + "</td></tr>";
								html += "<tr><td nowrap>sourceDir:</td><td>" + packageInfo.applicationInfo.sourceDir + "</td></tr>";
								html += "<tr><td nowrap>publicSourceDir:</td><td>" + packageInfo.applicationInfo.publicSourceDir + "</td></tr>";
								html += "<tr><td nowrap>dataDir:</td><td>" + packageInfo.applicationInfo.dataDir + "</td></tr>";
								html += "<tr><td nowrap>spaceManager:</td><td>" + packageInfo.applicationInfo.manageSpaceActivityName + "</td></tr>";
								html += "<tr><td nowrap>flags:</td><td>" + new BitSet(packageInfo.applicationInfo.flags).toString() + "</td></tr>";
								html += "<tr><td nowrap>permission:</td><td>" + packageInfo.applicationInfo.permission + "</td></tr>";
								html += "<tr><td nowrap>taskAffinity:</td><td>" + packageInfo.applicationInfo.taskAffinity + "</td></tr>";
								html += "<tr><td nowrap>targetSdkVersion:</td><td>" + packageInfo.applicationInfo.targetSdkVersion + "</td></tr>";
								html += "<tr><td nowrap>enabled:</td><td>" + ((packageInfo.applicationInfo.enabled) ? "true" : "false") + "</td></tr>";
								html += "<tr><td nowrap>sharedUserId:</td><td>" + packageInfo.sharedUserId + "</td></tr>";
								html += "<tr><td nowrap>sharedUserLabel:</td><td>" + packageInfo.sharedUserLabel + "</td></tr>";
								html += "<tr><td nowrap>versionCode:</td><td>" + packageInfo.versionCode + "</td></tr>";
								html += "<tr><td nowrap>versionName:</td><td>" + packageInfo.versionName + "</td></tr>";
								html += "<tr><td nowrap>installer:</td><td>" + pm.getInstallerPackageName(packageName) + "</td></tr>";
								html += "<tr><td nowrap>size:</td><td>" + RexseeApplicationManager.getSize_(browser.getContext(), packageName) + "</td></tr>";
								Intent intent = pm.getLaunchIntentForPackage(packageName);
								String intentString = (intent == null) ? "null" : intent.toUri(Intent.URI_INTENT_SCHEME);
								html += "<tr><td nowrap>intent:</td><td>" + intentString + "</td></tr>";
								html += "<tr><td nowrap>Activities:</td><td>";
								if (packageInfo.activities != null) {
									for (int i = 0; i < packageInfo.activities.length; i++) {
										ActivityInfo activityInfo = packageInfo.activities[i];
										html += "<div style='border:1px solid #888888;padding:5px;margin-bottom:5px;'>";
										html += "<div><b>name:</b>" + activityInfo.name + "</div>";
										html += "<div><b>label:</b>" + activityInfo.loadLabel(pm) + "</div>";
										html += "<div><b>processName:</b>" + activityInfo.processName + "</div>";
										html += "<div><b>launchMode:</b>" + RexseeApplicationManager.getLaunchMode_(activityInfo.launchMode) + "</div>";
										html += "<div><b>permission:</b>" + activityInfo.permission + "</div>";
										html += "<div><b>screenOrientation:</b>" + RexseeApplicationManager.getScreenOrientation_(activityInfo.screenOrientation) + "</div>";
										html += "<div><b>targetActivity:</b>" + activityInfo.targetActivity + "</div>";
										html += "<div><b>taskAffinity:</b>" + activityInfo.taskAffinity + "</div>";
										html += "<div><b>enabled:</b>" + ((activityInfo.enabled) ? "true" : "false") + "</div>";
										html += "<div><b>exported:</b>" + ((activityInfo.exported) ? "true" : "false") + "</div>";
										html += "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>Receivers:</td><td>";
								if (packageInfo.receivers != null) {
									for (int i = 0; i < packageInfo.receivers.length; i++) {
										ActivityInfo receiverInfo = packageInfo.receivers[i];
										html += "<div style='border:1px solid #888888;padding:5px;margin-bottom:5px;'>";
										html += "<div><b>name:</b>" + receiverInfo.name + "</div>";
										html += "<div><b>label:</b>" + receiverInfo.loadLabel(pm) + "</div>";
										html += "<div><b>processName:</b>" + receiverInfo.processName + "</div>";
										html += "<div><b>launchMode:</b>" + RexseeApplicationManager.getLaunchMode_(receiverInfo.launchMode) + "</div>";
										html += "<div><b>permission:</b>" + receiverInfo.permission + "</div>";
										html += "<div><b>screenOrientation:</b>" + RexseeApplicationManager.getScreenOrientation_(receiverInfo.screenOrientation) + "</div>";
										html += "<div><b>targetActivity:</b>" + receiverInfo.targetActivity + "</div>";
										html += "<div><b>taskAffinity:</b>" + receiverInfo.taskAffinity + "</div>";
										html += "<div><b>enabled:</b>" + ((receiverInfo.enabled) ? "true" : "false") + "</div>";
										html += "<div><b>exported:</b>" + ((receiverInfo.exported) ? "true" : "false") + "</div>";
										html += "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>Providers:</td><td>";
								if (packageInfo.providers != null) {
									for (int i = 0; i < packageInfo.providers.length; i++) {
										ProviderInfo providerInfo = packageInfo.providers[i];
										html += "<div style='border:1px solid #888888;padding:5px;margin-bottom:5px;'>";
										html += "<div><b>name:</b>" + providerInfo.name + "</div>";
										html += "<div><b>label:</b>" + providerInfo.loadLabel(browser.getContext().getPackageManager()) + "</div>";
										html += "<div><b>packageName:</b>" + providerInfo.packageName + "</div>";
										html += "<div><b>processName:</b>" + providerInfo.processName + "</div>";
										html += "<div><b>authority:</b>" + providerInfo.authority + "</div>";
										html += "<div><b>readPermission:</b>" + providerInfo.readPermission + "</div>";
										html += "<div><b>writePermission:</b>" + providerInfo.writePermission + "</div>";
										html += "<div><b>enabled:</b>" + ((providerInfo.enabled) ? "true" : "false") + "</div>";
										html += "<div><b>exported:</b>" + ((providerInfo.exported) ? "true" : "false") + "</div>";
										html += "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>Services:</td><td>";
								if (packageInfo.services != null) {
									for (int i = 0; i < packageInfo.services.length; i++) {
										ServiceInfo serviceInfo = packageInfo.services[i];
										html += "<div style='border:1px solid #888888;padding:5px;margin-bottom:5px;'>";
										html += "<div><b>name:</b>" + serviceInfo.name + "</div>";
										html += "<div><b>label:</b>" + serviceInfo.loadLabel(browser.getContext().getPackageManager()) + "</div>";
										html += "<div><b>processName:</b>" + serviceInfo.processName + "</div>";
										html += "<div><b>permission:</b>" + serviceInfo.permission + "</div>";
										html += "<div><b>enabled:</b>" + ((serviceInfo.enabled) ? "true" : "false") + "</div>";
										html += "<div><b>exported:</b>" + ((serviceInfo.exported) ? "true" : "false") + "</div>";
										html += "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>Permissions:</td><td>";
								if (packageInfo.permissions != null) {
									for (int i = 0; i < packageInfo.permissions.length; i++) {
										PermissionInfo permissionInfo = packageInfo.permissions[i];
										html += "<div style='border:1px solid #888888;padding:5px;margin-bottom:5px;'>";
										html += "<div><b>name:</b>" + permissionInfo.name + "</div>";
										html += "<div><b>description:</b>" + permissionInfo.loadDescription(browser.getContext().getPackageManager()) + "</div>";
										html += "<div><b>protectionLevel:</b>" + RexseeApplicationManager.getPermissionProtectionLevel_(permissionInfo.protectionLevel) + "</div>";
										html += "<div><b>group:</b>" + permissionInfo.group + "</div>";
										html += "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>UserPermissions:</td><td>";
								if (packageInfo.requestedPermissions != null) {
									for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
										html += "<div>" + packageInfo.requestedPermissions[i] + "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>Features:</td><td>";
								if (packageInfo.reqFeatures != null) {
									for (int i = 0; i < packageInfo.reqFeatures.length; i++) {
										html += "<div>" + packageInfo.reqFeatures[i].name + "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>GIDs:</td><td>";
								if (packageInfo.gids != null) {
									for (int i = 0; i < packageInfo.gids.length; i++) {
										html += "<div>" + packageInfo.gids[i] + "</div>";
									}
								}
								html += "</td></tr>";
								html += "<tr><td nowrap>SharedLibraryFiles:</td><td>";
								if (packageInfo.applicationInfo.sharedLibraryFiles != null) {
									for (int i = 0; i < packageInfo.applicationInfo.sharedLibraryFiles.length; i++) {
										html += "<div>" + packageInfo.applicationInfo.sharedLibraryFiles[i] + "</div>";
									}
								}
								html += "</td></tr>";
							} catch (Exception e) {
								html += "<tr><td><B>Exception:</B><br>" + e.getLocalizedMessage() + "</td><td>";
							}
							html += "</tbody></table>";
						}
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener("services://") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:14px;'>";
						ActivityManager activityManager = (ActivityManager) browser.getContext().getSystemService(Context.ACTIVITY_SERVICE);
						List<RunningServiceInfo> services = activityManager.getRunningServices(RexseeApplicationManager.MAX_NUM);
						Iterator<RunningServiceInfo> iterator = services.iterator();
						while (iterator.hasNext()) {
							RunningServiceInfo sInfo = iterator.next();
							html += "<tr><td onclick=\"window.open('apps://" + sInfo.service.getPackageName() + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;'>";
							html += "<div style='font-size:16px;'><b>" + sInfo.process + "</b></div>";
							html += "<div><b>pid:</b>" + sInfo.pid + "</div>";
							html += "<div><b>activeSince:</b>" + sInfo.activeSince + "</div>";
							html += "<div><b>restarting:</b>" + sInfo.restarting + "</div>";
							html += "<div><b>clientCount:</b>" + sInfo.clientCount + "</div>";
							html += "<div><b>crashCount:</b>" + sInfo.crashCount + "</div>";
							html += "<div><b>lastActivityTime:</b>" + sInfo.lastActivityTime + "</div>";
							html += "<div><b>clientPackage:</b>" + sInfo.clientPackage + "</div>";
							html += "<div><b>uid:</b>" + sInfo.uid + "</div>";
							html += "<div><b>foreground:</b>" + ((sInfo.foreground) ? "true" : "false") + "</div>";
							html += "<div><b>started:</b>" + ((sInfo.started) ? "true" : "false") + "</div>";
							html += "<div><b>packageName:</b>" + sInfo.service.getPackageName() + "</div>";
							html += "<div><b>className:</b>" + sInfo.service.getClassName() + "</div>";
							html += "</td></tr>";
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener("tasks://") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:14px;'>";
						ActivityManager am = (ActivityManager) browser.getContext().getSystemService(Context.ACTIVITY_SERVICE);
						List<RunningTaskInfo> tasks = am.getRunningTasks(RexseeApplicationManager.MAX_NUM);
						Iterator<RunningTaskInfo> iterator = tasks.iterator();
						while (iterator.hasNext()) {
							RunningTaskInfo tInfo = iterator.next();
							html += "<tr><td onclick=\"window.open('apps://" + tInfo.topActivity.getPackageName() + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;'>";
							html += "<div style='font-size:16px;'><b>" + tInfo.topActivity.getPackageName() + "</b></div>";
							html += "<div><b>id:</b>" + tInfo.id + "</div>";
							html += "<div><b>numActivities:</b>" + tInfo.numActivities + "</div>";
							html += "<div><b>numRunning:</b>" + tInfo.numRunning + "</div>";
							html += "<div><b>description:</b>" + tInfo.description + "</div>";
							html += "<div><b>baseActivity:</b>";
							ComponentName baseComponent = tInfo.baseActivity;
							html += "[packageName]" + baseComponent.getPackageName();
							html += "[className]" + baseComponent.getClassName();
							html += "[shortClassName]" + baseComponent.getShortClassName();
							html += "</div>";
							html += "<div><b>topActivity:</b>";
							ComponentName topComponent = tInfo.topActivity;
							html += "[packageName]" + topComponent.getPackageName();
							html += "[className]" + topComponent.getClassName();
							html += "[shortClassName]" + topComponent.getShortClassName();
							html += "</div>";
							html += "</td></tr>";
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener("providers://") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:14px;'>";
						PackageManager pm = browser.getContext().getPackageManager();
						List<ProviderInfo> providers = pm.queryContentProviders(null, 0, 0);
						if (providers != null) {
							Iterator<ProviderInfo> iterator = providers.iterator();
							while (iterator.hasNext()) {
								ProviderInfo providerInfo = iterator.next();
								html += "<tr><td onclick=\"window.open('apps://" + providerInfo.packageName + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;'>";
								html += "<div style='font-size:16px;'><b>" + providerInfo.loadLabel(pm) + "</b></div>";
								html += "<div><b>name:</b>" + providerInfo.name + "</div>";
								html += "<div><b>packageName:</b>" + providerInfo.packageName + "</div>";
								html += "<div><b>processName:</b>" + providerInfo.processName + "</div>";
								html += "<div><b>authority:</b>" + providerInfo.authority + "</div>";
								html += "<div><b>readPermission:</b>" + providerInfo.readPermission + "</div>";
								html += "<div><b>writePermission:</b>" + providerInfo.writePermission + "</div>";
								html += "<div><b>enabled:</b>" + ((providerInfo.enabled) ? "true" : "false") + "</div>";
								html += "<div><b>exported:</b>" + ((providerInfo.exported) ? "true" : "false") + "</div>";
								html += "</td></tr>";
							}
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});

		final String prefix = browser.application.resources.prefix;
		browser.urlListeners.add(new UrlListener(prefix + ":images") {
			@Override
			public void run(Context context, final Browser browser, final String url) {
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						ContentResolver contentResolver = browser.getContext().getContentResolver();
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						Cursor cursor = contentResolver.query(Uri.parse(RexseeUrl.URI_MEDIA_IMAGE), new String[]{"_id", "_data"}, null, null, "_id desc");
						html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
						if (cursor.getCount() == 0) {
							html += "<tr><td style='padding:10px;'>No image found.</td></tr>";
						} else {
							for (int i = 0; i < cursor.getCount(); i++) {
								cursor.moveToPosition(i);
								html += "<tr><td onclick=\"" + browser.function.getInterfaceName() + ".go('" + RexseeUrl.URI_MEDIA_IMAGE + "/" + cursor.getInt(0) + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>" + cursor.getString(1) + "</td></tr>";
							}
						}
						cursor.close();
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":video") {
			@Override
			public void run(Context context, final Browser browser, final String url) {
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						ContentResolver contentResolver = browser.getContext().getContentResolver();
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						Cursor cursor = contentResolver.query(Uri.parse(RexseeUrl.URI_MEDIA_VIDEO), new String[]{"_id", "_data"}, null, null, "_id desc");
						html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
						if (cursor.getCount() == 0) {
							html += "<tr><td style='padding:10px;'>No video found.</td></tr>";
						} else {
							for (int i = 0; i < cursor.getCount(); i++) {
								cursor.moveToPosition(i);
								html += "<tr><td onclick=\"" + browser.function.getInterfaceName() + ".go('" + RexseeUrl.URI_MEDIA_VIDEO + "/" + cursor.getInt(0) + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>" + cursor.getString(1) + "</td></tr>";
							}
						}
						cursor.close();
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":audio") {
			@Override
			public void run(Context context, final Browser browser, final String url) {
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						ContentResolver contentResolver = browser.getContext().getContentResolver();
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						Cursor cursor = contentResolver.query(Uri.parse(RexseeUrl.URI_MEDIA_AUDIO), new String[]{"_id", "_data"}, null, null, "_id desc");
						html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
						if (cursor.getCount() == 0) {
							html += "<tr><td style='padding:10px;'> audio found.</td></tr>";
						} else {
							for (int i = 0; i < cursor.getCount(); i++) {
								cursor.moveToPosition(i);
								html += "<tr><td onclick=\"" + browser.function.getInterfaceName() + ".go('" + RexseeUrl.URI_MEDIA_AUDIO + "/" + cursor.getInt(0) + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>" + cursor.getString(1) + "</td></tr>";
							}
						}
						cursor.close();
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":security") {
			@Override
			public void run(Context context, final Browser browser, final String url) {
				new Thread() {
					@Override
					public void run() {
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						Provider[] providers = Security.getProviders();
						html += "<table width=100% cellspacing=0 style='color:white;font-size:14px;'>";
						if (providers.length == 0) {
							html += "<tr><td style='padding:10px;'>No security provider found.</td></tr>";
						} else {
							for (int i = 0; i < providers.length; i++) {
								Provider provider = providers[i];
								html += "<tr><td style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>";
								html += "<div style='font-size:16px;font-weight:bold;'>" + provider.getName() + "&nbsp;[" + provider.getVersion() + "]</div>";
								html += "<div>" + provider.getInfo() + "</div>";
								Set<Service> services = provider.getServices();
								Iterator<Service> iterator = services.iterator();
								String srv = "";
								while (iterator.hasNext()) {
									Service s = iterator.next();
									srv += "<div style='margin-top:5px;background-color:#222222;padding:10px;border:1px solid #444444;color:#aaaaaa;'>";
									srv += "<B>[algorithm]</B>" + s.getAlgorithm();
									srv += "<br><B>[className]</B>" + s.getClassName();
									srv += "<br><B>[type]</B>" + s.getType();
									srv += "</div>";
								}
								html += srv;
								html += "</td></tr>";
							}
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":accounts") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				new Thread() {
					@Override
					public void run() {
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:18px;'>";
						AccountManager accountManager = AccountManager.get(context);
						Account[] accounts = accountManager.getAccounts();
						if (accounts.length == 0) {
							html += "<tr><td style='padding:10px;'>No accounts found.</td></tr>";
						} else {
							for (int i = 0; i < accounts.length; i++) {
								html += "<tr><td style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>" + accounts[i].name + "<div style='font-size:16px;color:#aaaaaa'>[" + accounts[i].type + "]</div>" + "</td></tr>";
							}
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":groupsOfContact") {
			@Override
			public void run(final Context context, final Browser browser, String url) {
				new Thread() {
					@Override
					public void run() {
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						String html = "<HTML><HEAD><TITLE>" + Groups.CONTENT_URI.toString() + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
						try {
							ContentResolver contentResolver = context.getContentResolver();
							Cursor cursor = contentResolver.query(Groups.CONTENT_URI, new String[]{Data._ID, Groups.TITLE}, null, null, Groups.TITLE);
							if (cursor == null || cursor.getCount() == 0) {
								html += "<tr><td style='padding:10px;'>No contact group found.</td></tr>";
							} else {
								for (int i = 0; i < cursor.getCount(); i++) {
									cursor.moveToPosition(i);
									html += "<tr><td style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;' onclick=\"" + browser.function.getInterfaceName() + ".go('" + Groups.CONTENT_URI.toString() + "/" + cursor.getInt(0) + "');\">" + cursor.getString(1) + "</td></tr>";
								}
							}
							cursor.close();
						} catch (Exception e) {
							html += "<tr><td style='padding:10px;'>Exception: " + e.getLocalizedMessage() + "</td></tr>";
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":contacts") {
			@Override
			public void run(final Context context, final Browser browser, final String url) {
				new Thread() {
					@Override
					public void run() {
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						String html = "<HTML><HEAD><TITLE>" + Contacts.CONTENT_URI.toString() + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
						try {
							ContentResolver contentResolver = context.getContentResolver();
							Cursor cursor = contentResolver.query(Contacts.CONTENT_URI, new String[]{Data._ID, Data.DISPLAY_NAME}, null, null, Data.DISPLAY_NAME);
							if (cursor == null || cursor.getCount() == 0) {
								html += "<tr><td style='padding:10px;'>No contacts found.</td></tr>";
							} else {
								for (int i = 0; i < cursor.getCount(); i++) {
									cursor.moveToPosition(i);
									html += "<tr><td style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;' onclick=\"" + browser.function.getInterfaceName() + ".go('" + Contacts.CONTENT_URI.toString() + "/" + cursor.getInt(0) + "');\">" + cursor.getString(1) + "</td></tr>";
								}
							}
							cursor.close();
						} catch (Exception e) {
							html += "<tr><td style='padding:10px;'>Exception: " + e.getLocalizedMessage() + "</td></tr>";
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":rawContacts") {
			@Override
			public void run(final Context context, final Browser browser, String url) {
				new Thread() {
					@Override
					public void run() {
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						String html = "<HTML><HEAD><TITLE>" + RawContacts.CONTENT_URI.toString() + "</TITLE></HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
						try {
							ContentResolver contentResolver = context.getContentResolver();
							Cursor cursor = contentResolver.query(RawContacts.CONTENT_URI, new String[]{Data._ID, Data.DISPLAY_NAME}, null, null, Data.DISPLAY_NAME);
							if (cursor == null || cursor.getCount() == 0) {
								html += "<tr><td style='padding:10px;'>No contacts found.</td></tr>";
							} else {
								for (int i = 0; i < cursor.getCount(); i++) {
									cursor.moveToPosition(i);
									html += "<tr><td style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;' onclick=\"" + browser.function.getInterfaceName() + ".go('" + RawContacts.CONTENT_URI.toString() + "/" + cursor.getInt(0) + "');\">" + cursor.getString(1) + "</td></tr>";
								}
							}
							cursor.close();
						} catch (Exception e) {
							html += "<tr><td style='padding:10px;'>Exception: " + e.getLocalizedMessage() + "</td></tr>";
						}
						html += "</table>";
						html += "</BODY>";
						html += "</HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					}
				}.start();
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return true;
			}
		});
	}

	public static void initRiskyUrlListener(Browser browser) {

		final String prefix = browser.application.resources.prefix;

		browser.urlListeners.add(new UrlListener("file://") {
			@Override
			public void run(Context context, final Browser browser, final String url) {
				if (url.startsWith(RexseeUrl.ASSET_URL)) {
					try {
						browser.pageBeforeStartListeners.run(browser, url);
						browser.loadUrl(url);
					} catch (Exception e) {
						browser.application.error("Asset Error: " + e.getLocalizedMessage());
					}
					return;
				}
				File file = new File(Uri.parse(url).getPath());
				if (!file.exists()) {
					browser.application.error(RexseeUrl.ERROR_FILE_NOT_FOUND);
					return;
				}
				String path = file.getAbsolutePath();
				if (file.isDirectory()) {
					if (file.canRead()) {
						String html = "<HTML><HEAD><TITLE>file://" + path + "</TITLE>";
						html += "<STYLE>a:link {color:white;text-decoration:none; } a:visited {color:white;text-decoration:none; } .item {border-bottom:1px solid #222222;font-size:16px; padding:10px;word-break:break-all;} td{font-size:16px;}</STYLE>";
						html += "</HEAD>";
						html += "<BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% style='font-size:16px;color:white;'>";
						if (!path.equals("/")) {
							html += "<tr><td><a href=\"file://" + file.getParent() + "\">"
									+ "<div class=item>..</div>"
									+ "</a></td></tr>";
						}
						browser.pageBeforeStartListeners.run(browser, url);
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						String[] list = file.list();
						Arrays.sort(list, Collator.getInstance(Locale.CHINA));
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						for (int i = 0; i < list.length; i++) {
							File child = new File(path + "/" + list[i]);
							if (child.isDirectory()) {
								html += "<tr><td><a href=\"file://" + ((path.compareTo("/") == 0) ? "/" + list[i] : path + "/" + list[i]) + "\">"
										+ "<div class=item><table width=100%><tr><td>+&nbsp;&nbsp;" + list[i] + "</td><td align=right></td></tr></table></div>"
										+ "</a></td></tr>";
							}
						}
						for (int i = 0; i < list.length; i++) {
							File child = new File(path + "/" + list[i]);
							if (child.isFile()) {
								long size = child.length();
								String sizeStr = (size > 1024) ? (int) (size / 1024) + "k" : String.valueOf(size);
								html += "<tr><td><a href=\"file://" + ((path.compareTo("/") == 0) ? "/" + list[i] : path + "/" + list[i]) + "\">"
										+ "<div class=item><table width=100%><tr><td>-&nbsp;&nbsp;" + list[i] + "</td><td align=right style='color:#888888;white-space:nowrap;'>" + sizeStr + "</td></tr></table></div>"
										+ "</a></td></tr>";
							}
						}
						for (int i = 0; i < list.length; i++) {
						}
						html += "</table></BODY></HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					} else {
						browser.application.error("Can't open the folder.");
					}
				} else {
					ExtensionListener fileListener = RexseeUrl.getExtensionByUrl(browser, path);
					if (fileListener != null && fileListener.shouldProcessLocal()) {
						fileListener.run(context, browser, url);
					} else {
						try {
							Intent i = new Intent();
							i.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
							i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
							i.setAction(Intent.ACTION_VIEW);
							i.setDataAndType(Uri.parse(url), Utilities.getMime(url));
							context.startActivity(i);
						} catch (Exception e) {
							browser.application.error("Can't open the file.");
						}
					}
				}
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				if (url.startsWith(RexseeUrl.ASSET_URL)) { return true; }
				File file = new File(Uri.parse(url).getPath());
				if (!file.exists()) { return false; }
				if (file.isDirectory() && file.canRead()) {
					return true;
				} else {
					ExtensionListener fileListener = RexseeUrl.getExtensionByUrl(browser, url);
					if (fileListener != null && fileListener.shouldProcessLocal()) {
						return fileListener.shouldAddToHistory(url);
					} else {
						return false;
					}
				}
			}
		});
		browser.urlListeners.add(new UrlListener("database://") {
			@Override
			public void run(Context context, Browser browser, String url) {
				String[] tmp = url.split("\\?table=");
				File file = new File(Uri.parse(tmp[0]).getPath());
				String path = file.getAbsolutePath();
				if (file.isDirectory()) {
					browser.function.go("file://" + path);
				} else {
					if (tmp.length == 1 && tmp[0].toLowerCase().endsWith(".db")) {
						String html = "<HTML><HEAD><TITLE>database://" + path + "</TITLE></HEAD><BODY style='margin:0px;background-color:black;color:white;'>";
						html += "<table width=100% style='font-size:16px;color:white;'>";
						if (!path.equals("/")) {
							html += "<tr onclick=\"" + prefix + "Browser.go('database://" + file.getParent() + "');\">"
									+ "<td style='border-bottom:1px solid #222222; padding:5px;'>..</td>"
									+ "</tr>";
						}
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						SQLiteDatabase db = RexseeDatabase.getDatabase(browser, tmp[0]);
						if (db != null) {
							try {
								Cursor cursor = db.rawQuery("SELECT name FROM " + RexseeDatabase.TABLE_MASTER + " WHERE type = 'table';", null);
								for (int i = 0; i < cursor.getCount(); i++) {
									cursor.moveToPosition(i);
									html += "<tr onclick=\"" + prefix + "Browser.go('database://" + path + "?table=" + cursor.getString(0) + "');\">"
											+ "<td style='border-bottom:1px solid #222222; padding:5px;word-break:break-all;'>+&nbsp;&nbsp;" + cursor.getString(0) + "</td>"
											+ "</tr>";
								}
								html += "</table></td></tr>";
								cursor.close();
							} catch (Exception e) {
							}
							db.close();
						}
						html += "</table></BODY></HTML>";
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					} else if (tmp.length > 1) {
						String sql = "SELECT * FROM " + tmp[1] + ";";
						browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
						String html = RexseeDatabase.queryForHTML(browser, sql, tmp[0]);
						browser.progressDialog.hide();
						browser.function.loadHTMLWithoutHistory(html);
					} else {
						browser.function.go("file://" + path);
					}
				}
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				String[] tmp = url.split("\\?table=");
				File file = new File(Uri.parse(tmp[0]).getPath());
				if (file.isDirectory() && file.canRead()) {
					return false;
				} else {
					if (tmp.length == 1 && tmp[0].toLowerCase().endsWith(".db")) {
						return true;
					} else if (tmp.length > 1) {
						return true;
					} else {
						return false;
					}
				}
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":private_file") {
			@Override
			public void run(Context context, Browser browser, String url) {
				browser.function.go("file://" + context.getCacheDir().getParent());
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});
		browser.urlListeners.add(new UrlListener(prefix + ":public_file") {
			@Override
			public void run(Context context, Browser browser, String url) {
				if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
					browser.application.error("SD card not ready.");
				} else {
					browser.function.go("file://" + Environment.getExternalStorageDirectory().getAbsolutePath());
				}
			}
			@Override
			public boolean shouldAddToHistory(Context context, Browser browser, String url) {
				return false;
			}
		});

	}

	public static void clearInterfaceMemory(Browser browser) {
		try {
			RexseeJavaView javaView = (RexseeJavaView) browser.interfaceList.get(browser.application.resources.prefix + RexseeJavaView.INTERFACE_NAME);
			if (javaView != null) javaView.destroyAll();
		} catch (Exception e) {
		}
		try {
			RexseePopupWindow window = (RexseePopupWindow) browser.interfaceList.get(browser.application.resources.prefix + RexseePopupWindow.INTERFACE_NAME);
			if (window != null) window.destroyAll();
		} catch (Exception e) {
		}
		try {
			RexseePageFlip flip = (RexseePageFlip) browser.interfaceList.get(browser.application.resources.prefix + RexseePageFlip.INTERFACE_NAME);
			if (flip != null) flip.destroyAll();
		} catch (Exception e) {
		}
	}

}
